package org.cip.esymons.tesoreria.tarea;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.cip.esymons.general.be.PersonaJuridica;
import org.cip.esymons.general.be.PersonaNatural;
import org.cip.esymons.general.util.ControladorAbstracto;
import org.cip.esymons.tesoreria.bc.CajaChicaDelegate;
import org.cip.esymons.tesoreria.bc.CierreCajaDelegate;
import org.cip.esymons.tesoreria.bc.CierreDocumentoDelegate;
import org.cip.esymons.tesoreria.bc.DetCajaChicaDelegate;
import org.cip.esymons.tesoreria.bc.DocumentoPagoDelegate;
import org.cip.esymons.tesoreria.bc.GeneracionCuotasDelegate;
import org.cip.esymons.tesoreria.bc.MovimientoCuentaDelegate;
import org.cip.esymons.tesoreria.bc.TipoCambioDelegate;
import org.cip.esymons.tesoreria.bc.TipoMonedaDelegate;
import org.cip.esymons.tesoreria.be.CajaChica;
import org.cip.esymons.tesoreria.be.CierreCaja;
import org.cip.esymons.tesoreria.be.CierreDocumento;
import org.cip.esymons.tesoreria.be.DetCajaChica;
import org.cip.esymons.tesoreria.be.DetPagoAgrupado;
import org.cip.esymons.tesoreria.be.DocumentoPago;
import org.cip.esymons.tesoreria.be.EnumEstadoCajaChica;
import org.cip.esymons.tesoreria.be.EnumEstadoCierreCaja;
import org.cip.esymons.tesoreria.be.EnumEstadoDetCajaChica;
import org.cip.esymons.tesoreria.be.EnumEstadoMovimiento;
import org.cip.esymons.tesoreria.be.EnumTipoCuentaIngreso;
import org.cip.esymons.tesoreria.be.EnumTipoDeuda;
import org.cip.esymons.tesoreria.be.MovimientoCuenta;
import org.cip.esymons.tesoreria.be.TipoMoneda;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;

public class TareaTesoreria implements Job {

    private GeneracionCuotasDelegate generacionCuotasDelegate;
    private CierreCajaDelegate delegadoCierreCaja;
    private DocumentoPagoDelegate delegadoDocumentoPago;
    private CierreDocumentoDelegate delegadoCierreDocumento;
    private DetCajaChicaDelegate detCajaChicaDelegate;
    private MovimientoCuentaDelegate delegadoMovimientoCuenta;
    private CajaChicaDelegate delegadoCajaChica;
    private TipoCambioDelegate tipoCambioDelegate;
    private TipoMonedaDelegate tipoMonedaDelegate;

    @Override
    public void execute(JobExecutionContext context)
            throws JobExecutionException {

        generacionCuotasDelegate = new GeneracionCuotasDelegate();
        generacionCuotasDelegate.actualizacionHabilidad();
        
        delegadoCierreCaja = new CierreCajaDelegate();
        delegadoDocumentoPago = new DocumentoPagoDelegate();
        delegadoCierreDocumento = new CierreDocumentoDelegate();
        tipoCambioDelegate = new TipoCambioDelegate();
        tipoMonedaDelegate = new TipoMonedaDelegate();
        detCajaChicaDelegate = new DetCajaChicaDelegate();
        delegadoMovimientoCuenta = new MovimientoCuentaDelegate();
        delegadoCajaChica = new CajaChicaDelegate();
        cerrarCajaTesoreria();
        cerrarCajaChica();

    }

    private void cerrarCajaTesoreria() {        
        CierreCaja cc = delegadoCierreCaja.cierreCajaACtual();
        if (cc != null) {
            cc.setEstado(EnumEstadoCierreCaja.Cerrado);
            delegadoCierreCaja.edit(cc);
            List<DocumentoPago> lista = delegadoDocumentoPago.buscarDocumentosDelDia(cc.getCieFecha());
            CierreDocumento cierreDocumento = new CierreDocumento();
            Double monto = 0.0;
            for (DocumentoPago dp : lista) {
                if (dp.getMonto() != null) {
                    monto += dp.getMonto();
                }
                cierreDocumento = new CierreDocumento();
                if (dp.getMonto() != null) {
                    cierreDocumento.setCdoMonto(dp.getMonto());
                } else {
                    cierreDocumento.setCdoMonto(0.0);
                }
                cierreDocumento.setDocumentoPago(dp);
                cierreDocumento.setCierreCaja(cc);
                delegadoCierreDocumento.create(cierreDocumento);
            }
            cc.setCieMonto(monto);
            cc.setArchivo(crearArchivoSisCont(cc).toString().getBytes());
            cc.setCieSincronizado(false);
            delegadoCierreCaja.edit(cc);
        }
    }

    private void cerrarCajaChica() {        
        List<CajaChica> lista = delegadoCajaChica.listarCajasParaTareaDeCierre(new Date());
        for (CajaChica cajaChica : lista) {
            CajaChica cc = cajaChica;
            Double montoTotalCajaDebe = cc.getCacDebe();
            List<DetCajaChica> detCaja = detCajaChicaDelegate.econtrarDetalle(cc.getCacCodigo());
            Double sumaDetCaja = 0.00;
            for (DetCajaChica detCajaChica : detCaja) {
                if (!detCajaChica.getEstado().equals(EnumEstadoDetCajaChica.ANULADO)) {
                    sumaDetCaja = sumaDetCaja + detCajaChica.getDecHaber();
                }
            }
            if (cc.getEstadoCajaChica().equals(EnumEstadoCajaChica.ACTIVA)) {
                Double montoRestanteCaja = 0.00;
                montoRestanteCaja = montoTotalCajaDebe - sumaDetCaja;
                cc.setEstadoCajaChica(EnumEstadoCajaChica.CERRADA);
                cc.setCacFecCierre(new Date());
                if (montoRestanteCaja <= 0) {
                    cc.setCacHaber(cc.getCacDebe());
                } else {
                    Calendar cal = Calendar.getInstance();
                    cal.setTime(new Date());
                    MovimientoCuenta mc = new MovimientoCuenta();
                    mc.setDescripcion("Devolucion de Caja Chica");
                    mc.setEstado(EnumEstadoMovimiento.Impaga);
                    mc.setFkSolCodigo(cc.getResponsable().getPersonaNatural());
                    mc.setMcuAnio(cal.get(Calendar.YEAR));
                    mc.setMcuFechvencimiento(cal.getTime());
                    mc.setMcuMes(cal.get(Calendar.MONTH) + 1);
                    mc.setMcuMonto(montoRestanteCaja);
                    mc.setMcuSaldo(montoRestanteCaja);
                    mc.setTipoDeuda(EnumTipoDeuda.OTROS);
                    delegadoMovimientoCuenta.create(mc);
                }
                delegadoCajaChica.edit(cc);
            }
        }
    }

    private StringBuilder crearArchivoSisCont(CierreCaja cc) {
        try {
            StringBuilder cadena = new StringBuilder("");
            SimpleDateFormat sd = new SimpleDateFormat("dd/MM/yy");
            Double tipoCambio = 0.0;
            HashMap ciSVC = new HashMap();
            TipoMoneda monedaDolar = null;
            List<TipoMoneda> listaMonedas = tipoMonedaDelegate.devolverMonedasNoSonPorDefecto(tipoMonedaDelegate.buscarMonedaDefecto());
            for (TipoMoneda tm : listaMonedas) {
                if (tm.getTmoDesc().toLowerCase().indexOf("dolar") >= 0) {
                    monedaDolar = tm;
                    break;
                }
            }
            tipoCambio = tipoCambioDelegate.buscarTipoCambioXFechaytipoMoneda(monedaDolar, cc.getCieFecha()).getTpcValor();
            if (cc != null) {
                List<DocumentoPago> lista = delegadoDocumentoPago.buscarDocumentosDelDia(cc.getCieFecha());
                for (DocumentoPago dp : lista) {
                    if (dp.getFkTdoCodigo().getTdoValorContable() != null) {
                        cadena.append("02");//TIPO DE COMPROBANTE
                        cadena.append(formatearCadena(cc.getCieNumeracion().toString(), "0", 4, "I"));//NUMERO DE COMPROBANTE
                        cadena.append(sd.format(cc.getCieFecha()));//FECHA DEL COMPROBANTE
                        cadena.append(formatearCadena("12".concat(dp.getFkTdoCodigo().getTdoValorContable()).concat(dp.getTmoCodigo().getTmoValorContable()), " ", 10, "D"));//CUENTA CONTABLE
                        cadena.append(formatearCadena(dp.getMonto().toString(), 12, 2));//MONTO
                        cadena.append("D");//AL DEBE O HABER (D/H)
                        cadena.append(dp.getTmoCodigo().getTmoSimboloContable());//MONEDA (S/D)
                        cadena.append(formatearCadena(tipoCambio.toString(), 10, 7));//TIPO DE CAMBIO
                        cadena.append(formatearCadena(dp.getFkTdoCodigo().getTdoValorSiscont(), "0", 2, "I"));//VALOR DEL TIPO DE DOCUMENTO EN EL SISCONT
                        cadena.append(formatearCadena(dp.getDocNumero(), " ", 20, "D"));//NÚMERO DEL DOCUMENTO
                        cadena.append(formatearCadena("", " ", 8, "D"));
                        //CÓDIGO DEL PROVEEDOR/CLIENTE
                        if (dp.getFkSolCodigo() instanceof PersonaJuridica) {
                            PersonaJuridica pj = (PersonaJuridica) dp.getFkSolCodigo();
                            if (pj.getNumeroRUC() != null && !pj.getNumeroRUC().isEmpty()) {
                                cadena.append(formatearCadena(pj.getNumeroRUC(), " ", 11, "D"));
                            } else {
                                cadena.append(formatearCadena(pj.getSolCodigo().toString(), " ", 11, "D"));
                            }
                        } else {
                            PersonaNatural pn = (PersonaNatural) dp.getFkSolCodigo();
                            if (pn.getNumeroDNI() != null && !pn.getNumeroDNI().isEmpty()) {
                                cadena.append(formatearCadena(pn.getNumeroDNI(), " ", 11, "D"));
                            } else {
                                if (pn.getNumeroRUC() != null && !pn.getNumeroRUC().isEmpty()) {
                                    cadena.append(formatearCadena(pn.getNumeroRUC(), " ", 11, "D"));
                                } else {
                                    cadena.append(formatearCadena(pn.getSolCodigo().toString(), " ", 11, "D"));
                                }
                            }
                        }
                        cadena.append(formatearCadena("", " ", 99, "D"));
                        //RAZÓN SOCIAL
                        if (dp.getFkSolCodigo() instanceof PersonaJuridica) {
                            PersonaJuridica pj = (PersonaJuridica) dp.getFkSolCodigo();
                            cadena.append(formatearCadena(pj.getEmprazonSocial(), " ", 40, "D"));
                        } else {
                            cadena.append(formatearCadena("", " ", 40, "D"));
                        }
                        cadena.append(formatearCadena("", " ", 34, "D"));
                        //APELLIDOS Y NOMBRES DEL CLIENTE
                        if (dp.getFkSolCodigo() instanceof PersonaNatural) {
                            PersonaNatural pn = (PersonaNatural) dp.getFkSolCodigo();
                            cadena.append(formatearCadena(pn.getPerapellidoPaterno(), " ", 20, "D"));
                            cadena.append(formatearCadena(pn.getPerapellidoMaterno(), " ", 20, "D"));
                            cadena.append(formatearCadena(pn.getPerNombres(), " ", 20, "D"));
                        } else {
                            cadena.append(formatearCadena("", " ", 60, "D"));
                        }
                        //creando detalle del archivo
                        for (DetPagoAgrupado detalle : delegadoDocumentoPago.buscarDetalleDocumento(dp.getDocCodigo())) {
                            if (((detalle.getCuentaIngreso().getTipo().equals(EnumTipoCuentaIngreso.Cuota_CIP) ||
                                    detalle.getCuentaIngreso().getTipo().equals(EnumTipoCuentaIngreso.Evento)) && detalle.isSubDetalle()) || (!detalle.getCuentaIngreso().getTipo().equals(EnumTipoCuentaIngreso.Cuota_CIP) &&
                                    !detalle.getCuentaIngreso().getTipo().equals(EnumTipoCuentaIngreso.Evento))) {
                                cadena.append("02");//TIPO DE COMPROBANTE
                                cadena.append(formatearCadena(cc.getCieNumeracion().toString(), "0", 4, "I"));//NUMERO DE COMPROBANTE
                                cadena.append(sd.format(cc.getCieFecha()));//FECHA DEL COMPROBANTE
                                cadena.append(formatearCadena(detalle.getCuentaIngreso() == null ? "000" : detalle.getCuentaIngreso().getFkCcoCodigo().getCcoCodigo(), " ", 10, "D"));//CUENTA CONTABLE
                                cadena.append(formatearCadena(detalle.getValor().toString(), 12, 2));//MONTO
                                cadena.append("H");//AL DEBE O HABER (D/H)
                                cadena.append(dp.getTmoCodigo().getTmoSimboloContable());//MONEDA (S/D)
                                cadena.append(formatearCadena(tipoCambio.toString(), 10, 7));//TIPO DE CAMBIO
                                cadena.append(formatearCadena(dp.getFkTdoCodigo().getTdoValorSiscont(), "0", 2, "I"));//VALOR DEL TIPO DE DOCUMENTO EN EL SISCONT
                                cadena.append(formatearCadena(dp.getDocNumero(), " ", 20, "D"));//NÚMERO DEL DOCUMENTO
                                cadena.append(formatearCadena("", " ", 8, "D"));
                                //CÓDIGO DEL PROVEEDOR/CLIENTE
                                if (dp.getFkSolCodigo() instanceof PersonaJuridica) {
                                    PersonaJuridica pj = (PersonaJuridica) dp.getFkSolCodigo();
                                    if (pj.getNumeroRUC() != null && !pj.getNumeroRUC().isEmpty()) {
                                        cadena.append(formatearCadena(pj.getNumeroRUC(), " ", 11, "D"));
                                    } else {
                                        cadena.append(formatearCadena(pj.getSolCodigo().toString(), " ", 11, "D"));
                                    }
                                } else {
                                    PersonaNatural pn = (PersonaNatural) dp.getFkSolCodigo();
                                    if (pn.getNumeroDNI() != null && !pn.getNumeroDNI().isEmpty()) {
                                        cadena.append(formatearCadena(pn.getNumeroDNI(), " ", 11, "D"));
                                    } else {
                                        if (pn.getNumeroRUC() != null && !pn.getNumeroRUC().isEmpty()) {
                                            cadena.append(formatearCadena(pn.getNumeroRUC(), " ", 11, "D"));
                                        } else {
                                            cadena.append(formatearCadena(pn.getSolCodigo().toString(), " ", 11, "D"));
                                        }
                                    }
                                }
                                cadena.append(formatearCadena("", " ", 8, "D"));
                                cadena.append(formatearCadena(detalle.getCuentaIngreso().getFkCcoCodigo().getPresupuesto().getPreCodigo(), " ", 10, "D"));//PRESUPUESTO
                                cadena.append(formatearCadena("", " ", 81, "D"));
                                //RAZÓN SOCIAL
                                if (dp.getFkSolCodigo() instanceof PersonaJuridica) {
                                    PersonaJuridica pj = (PersonaJuridica) dp.getFkSolCodigo();
                                    cadena.append(formatearCadena(pj.getEmprazonSocial(), " ", 40, "D"));
                                } else {
                                    cadena.append(formatearCadena("", " ", 40, "D"));
                                }
                                cadena.append(formatearCadena(detalle.getDescripcion(), " ", 30, "D"));  //GLOSA
                                cadena.append(formatearCadena("", " ", 4, "D"));
                                //APELLIDOS Y NOMBRES DEL CLIENTE
                                if (dp.getFkSolCodigo() instanceof PersonaNatural) {
                                    PersonaNatural pn = (PersonaNatural) dp.getFkSolCodigo();
                                    cadena.append(formatearCadena(pn.getPerapellidoPaterno(), " ", 20, "D"));
                                    cadena.append(formatearCadena(pn.getPerapellidoMaterno(), " ", 20, "D"));
                                    cadena.append(formatearCadena(pn.getPerNombres(), " ", 20, "D"));
                                } else {
                                    cadena.append(formatearCadena("", " ", 60, "D"));
                                }
                            }
                        }

                        //creando IGV del archivo
                        cadena.append("02");//TIPO DE COMPROBANTE
                        cadena.append(formatearCadena(cc.getCieNumeracion().toString(), "0", 4, "I"));//NUMERO DE COMPROBANTE
                        cadena.append(sd.format(cc.getCieFecha()));//FECHA DEL COMPROBANTE
                        cadena.append(formatearCadena("40111", " ", 10, "D"));//CUENTA CONTABLE
                        cadena.append(formatearCadena(dp.getDpaIgv().toString(), 12, 2));//MONTO
                        cadena.append("H");//AL DEBE O HABER (D/H)
                        cadena.append(dp.getTmoCodigo().getTmoSimboloContable());//MONEDA (S/D)
                        cadena.append(formatearCadena(tipoCambio.toString(), 10, 7));//TIPO DE CAMBIO
                        cadena.append(formatearCadena(dp.getFkTdoCodigo().getTdoValorSiscont(), "0", 2, "I"));//VALOR DEL TIPO DE DOCUMENTO EN EL SISCONT
                        cadena.append(formatearCadena(dp.getDocNumero(), " ", 20, "D"));//NÚMERO DEL DOCUMENTO
                        cadena.append(formatearCadena("", " ", 8, "D"));
                        //CÓDIGO DEL PROVEEDOR/CLIENTE
                        if (dp.getFkSolCodigo() instanceof PersonaJuridica) {
                            PersonaJuridica pj = (PersonaJuridica) dp.getFkSolCodigo();
                            if (pj.getNumeroRUC() != null && !pj.getNumeroRUC().isEmpty()) {
                                cadena.append(formatearCadena(pj.getNumeroRUC(), " ", 11, "D"));
                            } else {
                                cadena.append(formatearCadena(pj.getSolCodigo().toString(), " ", 11, "D"));
                            }
                        } else {
                            PersonaNatural pn = (PersonaNatural) dp.getFkSolCodigo();
                            if (pn.getNumeroDNI() != null && !pn.getNumeroDNI().isEmpty()) {
                                cadena.append(formatearCadena(pn.getNumeroDNI(), " ", 11, "D"));
                            } else {
                                if (pn.getNumeroRUC() != null && !pn.getNumeroRUC().isEmpty()) {
                                    cadena.append(formatearCadena(pn.getNumeroRUC(), " ", 11, "D"));
                                } else {
                                    cadena.append(formatearCadena(pn.getSolCodigo().toString(), " ", 11, "D"));
                                }
                            }
                        }
                        cadena.append(formatearCadena("", " ", 99, "D"));
                        //RAZÓN SOCIAL
                        if (dp.getFkSolCodigo() instanceof PersonaJuridica) {
                            PersonaJuridica pj = (PersonaJuridica) dp.getFkSolCodigo();
                            cadena.append(formatearCadena(pj.getEmprazonSocial(), " ", 40, "D"));
                        } else {
                            cadena.append(formatearCadena("", " ", 40, "D"));
                        }
                        cadena.append(formatearCadena("", " ", 34, "D"));
                        //APELLIDOS Y NOMBRES DEL CLIENTE
                        if (dp.getFkSolCodigo() instanceof PersonaNatural) {
                            PersonaNatural pn = (PersonaNatural) dp.getFkSolCodigo();
                            cadena.append(formatearCadena(pn.getPerapellidoPaterno(), " ", 20, "D"));
                            cadena.append(formatearCadena(pn.getPerapellidoMaterno(), " ", 20, "D"));
                            cadena.append(formatearCadena(pn.getPerNombres(), " ", 20, "D"));
                        } else {
                            cadena.append(formatearCadena("", " ", 60, "D"));
                        }
                        //creando fin del archivo
                        cadena.append("16");//TIPO DE COMPROBANTE
                        cadena.append(formatearCadena(cc.getCieNumeracion().toString(), "0", 4, "I"));//NUMERO DE COMPROBANTE
                        cadena.append(sd.format(cc.getCieFecha()));//FECHA DEL COMPROBANTE
                        cadena.append(formatearCadena("12".concat(dp.getFkTdoCodigo().getTdoValorContable()).concat(dp.getTmoCodigo().getTmoValorContable()), " ", 10, "D"));//CUENTA CONTABLE
                        cadena.append(formatearCadena(dp.getMonto().toString(), 12, 2));//MONTO
                        cadena.append("H");//AL DEBE O HABER (D/H)
                        cadena.append(dp.getTmoCodigo().getTmoSimboloContable());//MONEDA (S/D)
                        cadena.append(formatearCadena(tipoCambio.toString(), 10, 7));//TIPO DE CAMBIO
                        cadena.append(formatearCadena(dp.getFkTdoCodigo().getTdoValorSiscont(), "0", 2, "I"));//VALOR DEL TIPO DE DOCUMENTO EN EL SISCONT
                        cadena.append(formatearCadena(dp.getDocNumero(), " ", 20, "D"));//NÚMERO DEL DOCUMENTO
                        cadena.append(formatearCadena("", " ", 8, "D"));
                        //CÓDIGO DEL PROVEEDOR/CLIENTE
                        if (dp.getFkSolCodigo() instanceof PersonaJuridica) {
                            PersonaJuridica pj = (PersonaJuridica) dp.getFkSolCodigo();
                            if (pj.getNumeroRUC() != null && !pj.getNumeroRUC().isEmpty()) {
                                cadena.append(formatearCadena(pj.getNumeroRUC(), " ", 11, "D"));
                            } else {
                                cadena.append(formatearCadena(pj.getSolCodigo().toString(), " ", 11, "D"));
                            }
                        } else {
                            PersonaNatural pn = (PersonaNatural) dp.getFkSolCodigo();
                            if (pn.getNumeroDNI() != null && !pn.getNumeroDNI().isEmpty()) {
                                cadena.append(formatearCadena(pn.getNumeroDNI(), " ", 11, "D"));
                            } else {
                                if (pn.getNumeroRUC() != null && !pn.getNumeroRUC().isEmpty()) {
                                    cadena.append(formatearCadena(pn.getNumeroRUC(), " ", 11, "D"));
                                } else {
                                    cadena.append(formatearCadena(pn.getSolCodigo().toString(), " ", 11, "D"));
                                }
                            }
                        }
                        cadena.append(formatearCadena("", " ", 99, "D"));
                        //RAZÓN SOCIAL
                        if (dp.getFkSolCodigo() instanceof PersonaJuridica) {
                            PersonaJuridica pj = (PersonaJuridica) dp.getFkSolCodigo();
                            cadena.append(formatearCadena(pj.getEmprazonSocial(), " ", 40, "D"));
                        } else {
                            cadena.append(formatearCadena("", " ", 40, "D"));
                        }
                        cadena.append(formatearCadena("", " ", 34, "D"));
                        //APELLIDOS Y NOMBRES DEL CLIENTE
                        if (dp.getFkSolCodigo() instanceof PersonaNatural) {
                            PersonaNatural pn = (PersonaNatural) dp.getFkSolCodigo();
                            cadena.append(formatearCadena(pn.getPerapellidoPaterno(), " ", 20, "D"));
                            cadena.append(formatearCadena(pn.getPerapellidoMaterno(), " ", 20, "D"));
                            cadena.append(formatearCadena(pn.getPerNombres(), " ", 20, "D"));
                        } else {
                            cadena.append(formatearCadena("", " ", 60, "D"));
                        }
                    } else {
                        for (DetPagoAgrupado detalle : delegadoDocumentoPago.buscarDetalleDocumento(dp.getDocCodigo())) {
                            if (((detalle.getCuentaIngreso().getTipo().equals(EnumTipoCuentaIngreso.Cuota_CIP) ||
                                    detalle.getCuentaIngreso().getTipo().equals(EnumTipoCuentaIngreso.Evento)) && detalle.isSubDetalle()) || (!detalle.getCuentaIngreso().getTipo().equals(EnumTipoCuentaIngreso.Cuota_CIP) &&
                                    !detalle.getCuentaIngreso().getTipo().equals(EnumTipoCuentaIngreso.Evento))) {
                                HashMap valor = new HashMap();
                                Double monto = 0.0;
                                String codigoCI = detalle.getCuentaIngreso() == null ? "000" : detalle.getCuentaIngreso().getFkCcoCodigo().getCcoCodigo();
                                String descripcion = detalle.getCuentaIngreso() == null ? "Fraccionamiento" : detalle.getCuentaIngreso().getCinDesc();
                                if (ciSVC.containsKey(codigoCI)) {
                                    valor = (HashMap) ciSVC.get(codigoCI);
                                    if (valor.containsKey(dp.getTmoCodigo().getTmoSimboloContable())) {
                                        monto = (Double) valor.get(dp.getTmoCodigo().getTmoSimboloContable());
                                    }
                                } else {
                                    valor.put("concepto", codigoCI + " : " + descripcion);
                                }
                                valor.put(dp.getTmoCodigo().getTmoSimboloContable(), detalle.getValor() + monto);
                                ciSVC.put(codigoCI, valor);
                            }
                        }
                    }
                }

                HashMap mapaSumatoria = new HashMap();
                Iterator it = ciSVC.entrySet().iterator();
                while (it.hasNext()) {
                    Map.Entry e = (Map.Entry) it.next();
                    HashMap valor = (HashMap) e.getValue();
                    String concepto = valor.get("concepto").toString();
                    valor.remove("concepto");
                    Iterator itValor = valor.entrySet().iterator();
                    while (itValor.hasNext()) {
                        Map.Entry eValor = (Map.Entry) itValor.next();
                        Double montoValor = 0.0;
                        if (mapaSumatoria.containsKey(eValor.getKey())) {
                            montoValor = montoValor + (Double) mapaSumatoria.get(eValor.getKey());
                        }
                        mapaSumatoria.put(eValor.getKey(), montoValor + (Double) eValor.getValue());
                        cadena.append("16");//TIPO DE COMPROBANTE
                        cadena.append(formatearCadena(cc.getCieNumeracion().toString(), "0", 4, "I"));//NUMERO DE COMPROBANTE
                        cadena.append(sd.format(cc.getCieFecha()));//FECHA DEL COMPROBANTE
                        cadena.append(formatearCadena(e.getKey().toString(), " ", 10, "D"));//CUENTA CONTABLE
                        cadena.append(formatearCadena(eValor.getValue().toString(), 12, 2));//MONTO
                        cadena.append("H");//AL DEBE O HABER (D/H)
                        cadena.append(eValor.getKey());//MONEDA (S/D)
                        cadena.append(formatearCadena(tipoCambio.toString(), 10, 7));//TIPO DE CAMBIO
                        cadena.append(formatearCadena("", " ", 180, "D"));
                        cadena.append(formatearCadena(concepto, " ", 30, "D"));
                        cadena.append(formatearCadena("", " ", 64, "D"));
                    }
                }

                Iterator itSuma = mapaSumatoria.entrySet().iterator();
                while (itSuma.hasNext()) {
                    Map.Entry eSuma = (Map.Entry) itSuma.next();
                    cadena.append("16");//TIPO DE COMPROBANTE
                    cadena.append(formatearCadena(cc.getCieNumeracion().toString(), "0", 4, "I"));//NUMERO DE COMPROBANTE
                    cadena.append(sd.format(cc.getCieFecha()));//FECHA DEL COMPROBANTE
                    cadena.append(formatearCadena("101", " ", 10, "D"));//CUENTA CONTABLE
                    cadena.append(formatearCadena(eSuma.getValue().toString(), 12, 2));//MONTO
                    cadena.append("H");//AL DEBE O HABER (D/H)
                    cadena.append(eSuma.getKey());//MONEDA (S/D)
                    cadena.append(formatearCadena(tipoCambio.toString(), 10, 7));//TIPO DE CAMBIO
                    cadena.append(formatearCadena("", " ", 274, "D"));
                }
            }
            return cadena;
        } catch (Exception e) {
            ControladorAbstracto.error("Error al crear el archivo MSISCONT :" + e.getMessage());
            return new StringBuilder(" ");
        }
    }

    private String formatearCadena(String cadena, String caracter, int tamano, String lado) {
        if (cadena.length() > tamano) {
            cadena = cadena.substring(0, tamano);
        } else {
            int faltante = tamano - cadena.length();
            if (lado.equals("D")) {
                for (int i = 0; i < faltante; i++) {
                    cadena = cadena.concat(caracter);
                }
            } else {
                for (int i = 0; i < faltante; i++) {
                    cadena = caracter.concat(cadena);
                }
            }
        }
        return cadena;
    }

    private String formatearCadena(String cadena, int tamano, int decimal) {
        int tam = tamano - (decimal + 1);
        int pos = -1;
        if (cadena.indexOf(".") >= 0) {
            pos = cadena.indexOf(".");
        }
        String parteEntera = null;
        String parteDecimal = null;
        if (pos >= 0) {
            parteEntera = cadena.substring(0, pos);
            parteDecimal = cadena.substring(pos + 1);
        } else {
            parteEntera = cadena;
        }

        if (parteEntera.length() > tam) {
            parteEntera = parteEntera.substring(0, tam);
        } else {
            int faltante = tam - parteEntera.length();
            for (int i = 0; i < faltante; i++) {
                parteEntera = "0".concat(parteEntera);
            }
        }

        if (parteDecimal != null) {
            if (parteDecimal.isEmpty()) {
                parteDecimal = "00";
            } else {
                if (parteDecimal.length() > decimal) {
                    parteDecimal = parteDecimal.substring(0, decimal);
                } else {
                    int faltante = decimal - parteDecimal.length();
                    for (int i = 0; i < faltante; i++) {
                        parteDecimal = parteDecimal.concat("0");
                    }
                }
            }
        } else {
            parteDecimal = "00";
        }
        return parteEntera.concat(".").concat(parteDecimal);
    }
}

